﻿/*
<File>
	<Copyright>Copyright © 2007, Outcoder. All rights reserved.</Copyright>
	<License see="//License.txt"/>
	<Owner Name="Daniel Vaughan" Email="danielvaughan@outcoder.com"/>
	<CreationDate>2007/11/27 12:44</CreationDate>
	<LastSubmissionDate>$Date: $</LastSubmissionDate>
	<Version>$Revision: $</Version>
</File>
*/

using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Channels;
using System.Web;
using Outcoder.Logging.LogEntries;

namespace Outcoder.Logging
{
	/// <summary>
	///	Default implementation of the <see cref="IClogService"/>.
	/// </summary>
	[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
	public class ClogService : IClogService
	{
		//static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(ClogService));

		public ClientConfigurationData GetConfiguration(IClientInfo clientInfo)
		{
			try
			{
				/* Create new info to set the */
				var info = new ClientInfo(clientInfo) { IPAddress = GetIPAddress() };

				#region In development.
				//System.Net.IPAddress address = IPAddress.Parse(info.IPAddress);
				//log.Debug(string.Format("AddressFamilly: {0}, IsIPv6LinkLocal: {1}, IsIPv6SiteLocal: {2}, address.ToString(): {3}, bytes: {4}", 
				//	address.AddressFamily, address.IsIPv6LinkLocal, address.IsIPv6SiteLocal, address.ToString(), address.GetAddressBytes()));
				//StringBuilder sb = new StringBuilder();
				//foreach (byte b in address.GetAddressBytes())
				//{
				//	sb.Append(b);
				//}
				//log.Debug("bytes: " + sb.ToString());
				#endregion

				var configurationData = new ClientConfigurationData
											{
												LogLevel = Log.GetLogLevel(info),
												LogEnabled = Log.IsEnabled(LogEntryOrigin.Remote, info)
											};
				//&& configurationData.LogLevel != LogLevel.None;
				return configurationData;
			}
			catch (Exception ex)
			{
				System.Diagnostics.Debug.Fail("Unable to get configuration.",
					ex.Message + Environment.NewLine + ex.StackTrace);
				throw;
			}
		}

		public void WriteEntry(ILogEntry entryData)
		{
			try
			{
				/* The cast here corresponds with the [ServiceKnownType(typeof(LogEntryData))]
				 attribute in the ClogService. */
				ClientLogEntry logEntry = new ClientLogEntry((LogEntryData)entryData);
				string ipAddress = GetIPAddress();
				if (!string.IsNullOrEmpty(ipAddress))
				{
					logEntry.IPAddress = ipAddress;
				}

				Log.LogMessage(logEntry);
			}
			catch (Exception ex)
			{
				System.Diagnostics.Debug.Fail("Unable to write to log.",
					ex.Message + Environment.NewLine + ex.StackTrace);
				throw;
			}
		}

		public void WriteEntrySilverlight(ILogEntry entryData)
		{
			WriteEntry(entryData);
		}

		string GetIPAddress()
		{
			try
			{
				MessageProperties properties = OperationContext.Current.IncomingMessageProperties;
				if (!properties.ContainsKey(RemoteEndpointMessageProperty.Name))
				{
					return string.Empty;
				}
				RemoteEndpointMessageProperty endpoint = properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
				return endpoint.Address;
			}
			catch (HttpException ex)
			{
				if (ex.ErrorCode == -2147467259)
				{
					/* We assume that the request is not available because it originated 
					 * from this app domain and is localhost. */
					return "127.0.0.1";
				}
			}
			catch (Exception)
			{
				/* Ignore. */
			}
			return string.Empty;
		}
	}
}
